home *** CD-ROM | disk | FTP | other *** search
/ Windows News 2005 November / WNnov2005.iso / Windows / Equipement / hMailServer / hMailServer-4.1-Build-136.exe / {app} / PHPWebAdmin / include / minixml / classes / doc.inc.php next >
PHP Script  |  2004-10-25  |  22KB  |  800 lines

  1. <?php
  2. /***************************************************************************************************
  3. ****************************************************************************************************
  4. *****
  5. *****      MiniXML - PHP class library for generating and parsing XML.
  6. *****
  7. *****      Copyright (C) 2002,2003 Patrick Deegan, Psychogenic.com
  8. *****      All rights reserved.
  9. *****
  10. *****      http://minixml.psychogenic.com
  11. *****
  12. *****   This program is free software; you can redistribute
  13. *****   it and/or modify it under the terms of the GNU
  14. *****   General Public License as published by the Free
  15. *****   Software Foundation; either version 2 of the
  16. *****   License, or (at your option) any later version.
  17. *****
  18. *****   This program is distributed in the hope that it will
  19. *****   be useful, but WITHOUT ANY WARRANTY; without even
  20. *****   the implied warranty of MERCHANTABILITY or FITNESS
  21. *****   FOR A PARTICULAR PURPOSE.  See the GNU General
  22. *****   Public License for more details.
  23. *****
  24. *****   You should have received a copy of the GNU General
  25. *****   Public License along with this program; if not,
  26. *****   write to the Free Software Foundation, Inc., 675
  27. *****   Mass Ave, Cambridge, MA 02139, USA.
  28. *****
  29. *****
  30. *****   You may contact the author, Pat Deegan, through the
  31. *****   contact section at http://www.psychogenic.com
  32. *****
  33. *****   Much more information on using this API can be found on the
  34. *****   official MiniXML website - http://minixml.psychogenic.com
  35. *****    or within the Perl version (XML::Mini) available through CPAN
  36. *****
  37. ****************************************************************************************************
  38. ***************************************************************************************************/
  39.  
  40. define("MINIXML_COMPLETE_REGEX",'/<\s*([^\s>]+)([^>]+)?>(.*?)<\s*\/\\1\s*>\s*([^<]+)?(.*)|\s*<!--(.+?)-->\s*|^\s*<\s*([^\s>]+)([^>]*)\/\s*>\s*([^<>]+)?|<!\[CDATA\s*\[(.*?)\]\]\s*>|<!DOCTYPE\s*([^\[]*)\[(.*?)\]\s*>|<!ENTITY\s*([^"\'>]+)\s*(["\'])([^\14]+)\14\s*>|^([^<]+)(.*)/smi');
  41.  //                    10                         11       12                      13           14     15               16     17
  42.  
  43.  
  44. define("MINIXML_SIMPLE_REGEX",
  45.  //         1         2      3                    4       5          6                   7          8             9          10     11
  46. '/\s*<\s*([^\s>]+)([^>]+)?>(.*?)<\s*\/\\1\s*>\s*([^<]+)?(.*)|\s*<!--(.+?)-->\s*|\s*<\s*([^\s>]+)([^>]*)\/\s*>\s*([^<>]+)?|^([^<]+)(.*)/smi');
  47.  
  48.  
  49.  
  50. require_once(MINIXML_CLASSDIR . "/element.inc.php");
  51.  
  52. /***************************************************************************************************
  53. ****************************************************************************************************
  54. *****
  55. *****                      MiniXMLDoc
  56. *****
  57. ****************************************************************************************************
  58. ***************************************************************************************************/
  59.  
  60. /* MiniXMLDoc class
  61. **
  62. ** The MiniXMLDoc class is the programmer's handle to MiniXML functionality.
  63. **
  64. ** A MiniXMLDoc instance is created in every program that uses MiniXML.
  65. ** With the MiniXMLDoc object, you can access the root MiniXMLElement,
  66. ** find/fetch/create elements and read in or output XML strings.
  67. **/
  68. class MiniXMLDoc {
  69.     var $xxmlDoc;
  70.     var $xuseSimpleRegex;
  71.     var $xRegexIndex;
  72.  
  73.     /* MiniXMLDoc [XMLSTRING]
  74.     ** Constructor, create and init a MiniXMLDoc object.
  75.     **
  76.     ** If the optional XMLSTRING is passed, the document will be initialised with
  77.     ** a call to fromString using the XMLSTRING.
  78.     **
  79.     */
  80.     function MiniXMLDoc ($string=NULL)
  81.     {
  82.         /* Set up the root element - note that it's name get's translated to a
  83.         ** <? xml version="1.0" ?> string.
  84.         */
  85.         $this->xxmlDoc = new MiniXMLElement("PSYCHOGENIC_ROOT_ELEMENT");
  86.         $this->xuseSimpleRegex = MINIXML_USE_SIMPLE;
  87.         if (! is_null($string))
  88.         {
  89.             $this->fromString($string);
  90.         }
  91.     }
  92.  
  93.     function init ()
  94.     {
  95.         $this->xxmlDoc = new MiniXMLElement("PSYCHOGENIC_ROOT_ELEMENT");
  96.     }
  97.  
  98.     /* getRoot
  99.     ** Returns a reference the this document's root element
  100.     ** (an instance of MiniXMLElement)
  101.     */
  102.     function &getRoot ()
  103.     {
  104.         return $this->xxmlDoc;
  105.     }
  106.  
  107.     /* setRoot NEWROOT
  108.     ** Set the document root to the NEWROOT MiniXMLElement object.
  109.     **/
  110.     function setRoot (&$root)
  111.     {
  112.         if ($this->isElement($root))
  113.         {
  114.             $this->xxmlDoc = $root;
  115.         } else {
  116.             return _MiniXMLError("MiniXMLDoc::setRoot(): Trying to set non-MiniXMLElement as root");
  117.         }
  118.     }
  119.  
  120.  
  121.     /* isElement ELEMENT
  122.     ** Returns a true value if ELEMENT is an instance of MiniXMLElement,
  123.     ** false otherwise.
  124.     */
  125.     function isElement (&$testme)
  126.     {
  127.         if (is_null($testme))
  128.         {
  129.             return 0;
  130.         }
  131.  
  132.         return method_exists($testme, 'MiniXMLElement');
  133.     }
  134.  
  135.  
  136.     /* isNode NODE
  137.     ** Returns a true value if NODE is an instance of MiniXMLNode,
  138.     ** false otherwise.
  139.     */
  140.     function isNode (&$testme)
  141.     {
  142.         if (is_null($testme))
  143.         {
  144.             return 0;
  145.         }
  146.  
  147.         return method_exists($testme, 'MiniXMLNode');
  148.     }
  149.  
  150.  
  151.     /* createElement NAME [VALUE]
  152.     ** Creates a new MiniXMLElement with name NAME.
  153.     ** This element is an orphan (has no assigned parent)
  154.     ** and will be lost unless it is appended (MiniXMLElement::appendChild())
  155.     ** to an element at some point.
  156.     **
  157.     ** If the optional VALUE (string or numeric) parameter is passed,
  158.     ** the new element's text/numeric content will be set using VALUE.
  159.     **
  160.     ** Returns a reference to the newly created element (use the =& operator)
  161.     */
  162.     function &createElement ($name=NULL, $value=NULL)
  163.     {
  164.         $newElement = new MiniXMLElement($name);
  165.  
  166.         if (! is_null($value))
  167.         {
  168.             if (is_numeric($value))
  169.             {
  170.                 $newElement->numeric($value);
  171.             } elseif (is_string($value))
  172.             {
  173.                 $newElement->text($value);
  174.             }
  175.         }
  176.  
  177.         return $newElement;
  178.     }
  179.  
  180.     /* getElement NAME
  181.     ** Searches the document for an element with name NAME.
  182.     **
  183.     ** Returns a reference to the first MiniXMLElement with name NAME,
  184.     ** if found, NULL otherwise.
  185.     **
  186.     ** NOTE: The search is performed like this, returning the first
  187.     **      element that matches:
  188.     **
  189.     ** - Check the Root Element's immediate children (in order) for a match.
  190.     ** - Ask each immediate child (in order) to MiniXMLElement::getElement()
  191.     **  (each child will then proceed similarly, checking all it's immediate
  192.     **   children in order and then asking them to getElement())
  193.     */
  194.     function &getElement ($name)
  195.     {
  196.  
  197.         $element = $this->xxmlDoc->getElement($name);
  198.         if (MINIXML_DEBUG > 0)
  199.         {
  200.             _MiniXMLLog("MiniXMLDoc::getElement(): Returning element $element");
  201.         }
  202.  
  203.         return $element;
  204.  
  205.     }
  206.  
  207.  
  208.     /* getElementByPath PATH
  209.     ** Attempts to return a reference to the (first) element at PATH
  210.     ** where PATH is the path in the structure from the root element to
  211.     ** the requested element.
  212.     **
  213.     ** For example, in the document represented by:
  214.     **
  215.     **     <partRateRequest>
  216.     **      <vendor>
  217.     **       <accessid user="myusername" password="mypassword" />
  218.     **      </vendor>
  219.     **      <partList>
  220.     **       <partNum>
  221.     **        DA42
  222.     **       </partNum>
  223.     **       <partNum>
  224.     **        D99983FFF
  225.     **       </partNum>
  226.     **       <partNum>
  227.     **        ss-839uent
  228.     **       </partNum>
  229.     **      </partList>
  230.     **     </partRateRequest>
  231.     **
  232.     **     $accessid =& $xmlDocument->getElementByPath('partRateRequest/vendor/accessid');
  233.     **
  234.     ** Will return what you expect (the accessid element with attributes user = "myusername"
  235.     ** and password = "mypassword").
  236.     **
  237.     ** BUT be careful:
  238.     **    $accessid =& $xmlDocument->getElementByPath('partRateRequest/partList/partNum');
  239.     **
  240.     ** will return the partNum element with the value "DA42".  Other partNums are
  241.     ** inaccessible by getElementByPath() - Use MiniXMLElement::getAllChildren() instead.
  242.     **
  243.     ** Returns the MiniXMLElement reference if found, NULL otherwise.
  244.     */
  245.     function &getElementByPath ($path)
  246.     {
  247.  
  248.         $element = $this->xxmlDoc->getElementByPath($path);
  249.         if (MINIXML_DEBUG > 0)
  250.         {
  251.             _MiniXMLLog("Returning element $element");
  252.         }
  253.  
  254.         return $element;
  255.  
  256.     }
  257.  
  258.     function fromFile ($filename)
  259.     {
  260.         $modified = stat($filename);
  261.         if (! is_array($modified))
  262.         {
  263.             _MiniXMLError("Can't stat '$filename'");
  264.             return NULL;
  265.         }
  266.  
  267.         if (MINIXML_USEFROMFILECACHING > 0)
  268.         {
  269.  
  270.             $tmpName = MINIXML_FROMFILECACHEDIR . '/' . 'minixml-' . md5($filename);
  271.             if (MINIXML_DEBUG > 0)
  272.             {
  273.                     _MiniXMLLog("Trying to open cach file $tmpName (for '$filename')");
  274.             }
  275.             $cacheFileStat = stat($tmpName);
  276.  
  277.             if (is_array($cacheFileStat) && $cacheFileStat[9] > $modified[9])
  278.             {
  279.  
  280.                 $fp = @fopen($tmpName,"r");
  281.                 if ($fp)
  282.                 {
  283.                     if (MINIXML_DEBUG > 0)
  284.                     {
  285.                         _MiniXMLLog("Reading file '$filename' from object cache instead ($tmpName)");
  286.                     }
  287.                     $tmpFileSize = filesize($tmpName);
  288.                     $tmpFileContents = fread($fp, $tmpFileSize);
  289.  
  290.                     $serializedObj = unserialize($tmpFileContents);
  291.  
  292.                     $sRoot =& $serializedObj->getRoot();
  293.                     if ($sRoot)
  294.                     {
  295.                         if (MINIXML_DEBUG > 0)
  296.                         {
  297.                             _MiniXMLLog("Restoring object from cache file $tmpName");
  298.                         }
  299.                         $this->setRoot($sRoot);
  300.  
  301.                         /* Return immediately, such that we don't refresh the cache */
  302.                         return $this->xxmlDoc->numChildren();
  303.  
  304.                     } /* end if we got a root element from unserialized object */
  305.  
  306.                 } /* end if we sucessfully opened the file */
  307.  
  308.  
  309.             } /* end if cache file exists and is more recent */
  310.         }
  311.  
  312.  
  313.         ob_start();
  314.         readfile($filename);
  315.         $filecontents = ob_get_contents();
  316.         ob_end_clean();
  317.  
  318.         $retVal = $this->fromString($filecontents);
  319.  
  320.         if (MINIXML_USEFROMFILECACHING > 0)
  321.         {
  322.             $this->saveToCache($filename);
  323.         }
  324.  
  325.         return $retVal;
  326.     }
  327.  
  328.     function saveToCache ($filename)
  329.     {
  330.         $tmpName = MINIXML_FROMFILECACHEDIR . '/' . 'minixml-' . md5($filename);
  331.  
  332.         $fp = @fopen($tmpName, "w");
  333.  
  334.         if (MINIXML_DEBUG > 0)
  335.         {
  336.             _MiniXMLLog("Saving object to cache as '$tmpName'");
  337.         }
  338.  
  339.         if ($fp)
  340.         {
  341.  
  342.             $serialized = serialize($this);
  343.             fwrite($fp, $serialized);
  344.  
  345.             fclose($fp);
  346.         } else {
  347.             _MiniXMLError("Could not open $tmpName for write in MiniXMLDoc::saveToCache()");
  348.         }
  349.  
  350.     }
  351.  
  352.     /* fromString XMLSTRING
  353.     **
  354.     ** Initialise the MiniXMLDoc (and it's root MiniXMLElement) using the
  355.     ** XML string XMLSTRING.
  356.     **
  357.     ** Returns the number of immediate children the root MiniXMLElement now
  358.     ** has.
  359.     */
  360.     function fromString (&$XMLString)
  361.     {
  362.         $useSimpleFlag = $this->xuseSimpleRegex;
  363.  
  364.  
  365.         if ($this->xuseSimpleRegex || ! preg_match('/<!DOCTYPE|<!ENTITY|<!\[CDATA/smi', $XMLString))
  366.         {
  367.             $this->xuseSimpleRegex = 1;
  368.  
  369.             $this->xRegexIndex = array(
  370.                             'biname'    => 1,
  371.                             'biattr'    => 2,
  372.                             'biencl'    => 3,
  373.                             'biendtxt'    => 4,
  374.                             'birest'    => 5,
  375.                             'comment'    => 6,
  376.                             'uname'        => 7,
  377.                             'uattr'        => 8,
  378.                             'uendtxt'    => 9,
  379.                             'plaintxt'    => 10,
  380.                             'plainrest'    => 11
  381.                         );
  382.             $regex = MINIXML_SIMPLE_REGEX;
  383.  
  384.         } else {
  385.  
  386.             $this->xRegexIndex = array(
  387.                             'biname'    => 1,
  388.                             'biattr'    => 2,
  389.                             'biencl'    => 3,
  390.                             'biendtxt'    => 4,
  391.                             'birest'    => 5,
  392.                             'comment'    => 6,
  393.                             'uname'        => 7,
  394.                             'uattr'        => 8,
  395.                             'uendtxt'    => 9,
  396.                             'cdata'        => 10,
  397.                             'doctypedef'    => 11,
  398.                             'doctypecont'    => 12,
  399.                             'entityname'    => 13,
  400.                             'entitydef'    => 15,
  401.                             'plaintxt'    => 16,
  402.                             'plainrest'    => 17
  403.                 );
  404.             $regex = MINIXML_COMPLETE_REGEX;
  405.         }
  406.  
  407.         $this->fromSubString($this->xxmlDoc, $XMLString, $regex);
  408.         $this->xuseSimpleRegex = $useSimpleFlag;
  409.         return $this->xxmlDoc->numChildren();
  410.     }
  411.  
  412.  
  413.     function fromArray (&$init, $params=NULL)
  414.     {
  415.         $this->init();
  416.         if (! is_array($init) )
  417.         {
  418.             return _MiniXMLError("MiniXMLDoc::fromArray(): Must Pass an ARRAY to initialize from");
  419.         }
  420.  
  421.         if (! is_array($params) )
  422.         {
  423.             $params = array();
  424.         }
  425.  
  426.         if ( isset($params["attributes"]) && is_array($params["attributes"]) )
  427.         {
  428.             $attribs= array();
  429.             foreach ($params["attributes"] as $attribName => $value)
  430.             {
  431.                 if (! is_array($attribs[$attribName]) )
  432.                 {
  433.                     $attribs[$attribName] = array();
  434.                 }
  435.  
  436.                 if (is_array($value))
  437.                 {
  438.                     foreach ($value as $v)
  439.                     {
  440.                         $attribs[$attribName][$v]++;
  441.                     }
  442.                 } else {
  443.                     $attribs[$attribName][$value]++;
  444.                 }
  445.             }
  446.  
  447.             // completely replace old attributes by our optimized array
  448.             $params["attributes"] = $attribs;
  449.         } else {
  450.             $params["attributes"] = array();
  451.         }
  452.  
  453.         foreach ($init as $keyname => $value)
  454.         {
  455.             $sub = $this->_fromArray_getExtractSub($value);
  456.  
  457.  
  458.             $this->$sub($keyname, $value, $this->xxmlDoc, $params);
  459.         }
  460.         return $this->xxmlDoc->numChildren();
  461.     }
  462.  
  463.     function _fromArray_getExtractSub ($v)
  464.     {
  465.         // is it a string, a numerical array or an associative array?
  466.         $sub = "_fromArray_extract";
  467.         if (is_array($v))
  468.         {
  469.             if (_MiniXML_NumKeyArray($v))
  470.             {
  471.                 // All numeric - assume it is a "straight" array
  472.                 $sub .= "ARRAY";
  473.             } else {
  474.                 $sub .= "AssociativeARRAY";
  475.             }
  476.  
  477.         } else {
  478.             $sub .= "STRING";
  479.         }
  480.         return $sub;
  481.     }
  482.  
  483.     function _fromArray_extractAssociativeARRAY ($name, &$value, &$parent, &$params)
  484.     {
  485.         $thisElement =& $parent->createChild($name);
  486.  
  487.         foreach ($value as $key => $val)
  488.         {
  489.             $sub = $this->_fromArray_getExtractSub($val);
  490.             $this->$sub($key, $val, $thisElement, $params);
  491.         }
  492.  
  493.         return;
  494.     }
  495.  
  496.     function _fromArray_extractARRAY ($name, &$value, &$parent, &$params)
  497.     {
  498.         foreach ($value as $val)
  499.         {
  500.             $sub = $this->_fromArray_getExtractSub($val);
  501.             $this->$sub($name, $val, $parent, $params);
  502.         }
  503.  
  504.         return;
  505.     }
  506.  
  507.  
  508.     function _fromArray_extractSTRING ($name, $value="", &$parent, &$params)
  509.     {
  510.  
  511.         $pname = $parent->name();
  512.  
  513.         if (
  514.             (isset($params['attributes'][$pname]) &&  is_array($params['attributes'][$pname]) && $params['attributes'][$pname][$name])
  515.              || ( isset($params['attributes']['-all']) && is_array($params['attributes']['-all']) && $params['attributes']['-all'][$name])
  516.            )
  517.         {
  518.             $parent->attribute($name, $value);
  519.         } elseif ($name == '-content') {
  520.  
  521.             $parent->text($value);
  522.         } else {
  523.             $parent->createChild($name, $value);
  524.         }
  525.  
  526.         return;
  527.     }
  528.  
  529.  
  530.  
  531.     function time ($msg)
  532.     {
  533.         if (MINIXML_DEBUG > 0)
  534.             _MiniXMLLog("\nMiniXML msg '$msg', time: ". time() . "\n");
  535.     }
  536.     // fromSubString PARENTMINIXMLELEMENT XMLSUBSTRING
  537.     // private method, called recursively to parse the XMLString in little sub-chunks.
  538.     function fromSubString (&$parentElement, &$XMLString, &$regex)
  539.     {
  540.         if (is_null($parentElement) || preg_match('/^\s*$/', $XMLString))
  541.         {
  542.             return;
  543.         }
  544.         if (MINIXML_DEBUG > 0)
  545.         {
  546.             _MiniXMLLog("Called fromSubString() with parent '" . $parentElement->name() . "'\n");
  547.         }
  548.  
  549.         $matches = array();
  550.  
  551.         if (preg_match_all(  $regex, $XMLString, $matches))
  552.         {
  553.             $mcp = $matches;
  554.             $numMatches = count($mcp[0]);
  555.  
  556.             if (MINIXML_DEBUG > 0)
  557.                 _MiniXMLLog ("Got $numMatches parsing regex matches: ". $mcp[0][0]);
  558.  
  559.             for($i=0; $i < $numMatches; $i++)
  560.             {
  561.                 if (MINIXML_DEBUG > 0)
  562.                     _MiniXMLLog ("Got $numMatches CHEKKING: ". $mcp[0][$i] . "\n");
  563.  
  564.                 $uname = $mcp[$this->xRegexIndex['uname']][$i];
  565.                 $comment = $mcp[$this->xRegexIndex['comment']][$i];
  566.                 if ($this->xuseSimpleRegex)
  567.                 {
  568.                     $cdata = NULL;
  569.                     $doctypecont = NULL;
  570.                     $entityname = NULL;
  571.                 } else {
  572.  
  573.                     $cdata = $mcp[$this->xRegexIndex['cdata']][$i];
  574.                     $doctypecont = $mcp[$this->xRegexIndex['doctypecont']][$i];
  575.                     $entityname = $mcp[$this->xRegexIndex['entityname']][$i];
  576.                 }
  577.  
  578.                 $plaintext = $mcp[$this->xRegexIndex['plaintxt']][$i];
  579.  
  580.                 if ($uname)
  581.                 {
  582.                     if (MINIXML_DEBUG > 0)
  583.                         _MiniXMLLog ("Got unary $uname");
  584.                     $ufinaltxt = $mcp[$this->xRegexIndex['uendtxt']][$i];
  585.                     $newElement =& $parentElement->createChild($uname);
  586.                     $this->_extractAttributesFromString($newElement, $mcp[$this->xRegexIndex['uattr']][$i]);
  587.                     if ($ufinaltxt)
  588.                     {
  589.                         $parentElement->createNode($ufinaltxt);
  590.                     }
  591.                 } elseif ($comment) {
  592.                     if (MINIXML_DEBUG > 0)
  593.                         _MiniXMLLog ("Got comment $comment");
  594.                     $parentElement->comment($comment);
  595.  
  596.                 } elseif ($cdata) {
  597.                     $newElement = new MiniXMLElementCData($cdata);
  598.                     $parentElement->appendChild($newElement);
  599.                 } elseif ($doctypecont) {
  600.  
  601.                     $newElement = new MiniXMLElementDocType($mcp[$this->xRegexIndex['doctypedef']][$i]);
  602.                     $appendedChild =& $parentElement->appendChild($newElement);
  603.                     $this->fromSubString($appendedChild, $doctypecont, $regex);
  604.  
  605.                 } elseif ($entityname ) {
  606.                     $newElement = new MiniXMLElementEntity ($entityname, $mcp[$this->xRegexIndex['entitydef']][$i]);
  607.                     $parentElement->appendChild($newElement);
  608.  
  609.                 } elseif ($plaintext) {
  610.  
  611.                     $afterTxt = $mcp[$this->xRegexIndex['plainrest']][$i];
  612.                     if (! preg_match('/^\s+$/', $plaintext))
  613.                     {
  614.                         $parentElement->createNode($plaintext);
  615.                     }
  616.  
  617.                     if ($afterTxt && ! preg_match('/^\s*$/', $afterTxt))
  618.                     {
  619.                         $this->fromSubString($parentElement, $afterTxt, $regex);
  620.                     }
  621.                 } elseif($mcp[$this->xRegexIndex['biname']]) {
  622.  
  623.                     $nencl = $mcp[$this->xRegexIndex['biencl']][$i];
  624.                     $finaltxt = $mcp[$this->xRegexIndex['biendtxt']][$i];
  625.                     $otherTags = $mcp[$this->xRegexIndex['birest']][$i];
  626.  
  627.                     $newElement =& $parentElement->createChild($mcp[$this->xRegexIndex['biname']][$i]);
  628.                     $this->_extractAttributesFromString($newElement, $mcp[$this->xRegexIndex['biattr']][$i]);
  629.                     $plaintxtMatches = array();
  630.                     if (preg_match("/^\s*([^\s<][^<]*)/", $nencl, $plaintxtMatches))
  631.                     {
  632.                         $txt = $plaintxtMatches[1];
  633.                         $newElement->createNode($txt);
  634.                         $nencl = preg_replace("/^\s*([^<]+)/", "", $nencl);
  635.                     }
  636.  
  637.                     if ($nencl && !preg_match('/^\s*$/', $nencl))
  638.                     {
  639.                         $this->fromSubString($newElement, $nencl, $regex);
  640.                     }
  641.  
  642.                     if ($finaltxt)
  643.                     {
  644.                         $parentElement->createNode($finaltxt);
  645.                     }
  646.  
  647.                     if ($otherTags && !preg_match('/^\s*$/',$otherTags))
  648.                     {
  649.                         $this->fromSubString($parentElement, $otherTags, $regex);
  650.                     }
  651.  
  652.  
  653.                 } /* end switch over type of match */
  654.             } /* end loop over all matches */
  655.         } /* end if there was a match */
  656.     } /* end method fromSubString */
  657.  
  658.  
  659.     /* toString [DEPTH]
  660.     ** Converts this MiniXMLDoc object to a string and returns it.
  661.     **
  662.     ** The optional DEPTH may be passed to set the space offset for the
  663.     ** first element.
  664.     **
  665.     ** If the optional DEPTH is set to MINIXML_NOWHITESPACES.
  666.     ** When it is, no \n or whitespaces will be inserted in the xml string
  667.     ** (ie it will all be on a single line with no spaces between the tags.
  668.     **
  669.     ** Returns a string of XML representing the document.
  670.     */
  671.     function toString ($depth=0)
  672.     {
  673.         $retString = $this->xxmlDoc->toString($depth);
  674.  
  675.         if ($depth == MINIXML_NOWHITESPACES)
  676.         {
  677.             $xmlhead = "<?xml version=\"1.0\"\\1?>";
  678.         } else {
  679.             $xmlhead = "<?xml version=\"1.0\"\\1?>\n ";
  680.         }
  681.         $search = array("/<PSYCHOGENIC_ROOT_ELEMENT([^>]*)>\s*/smi",
  682.                 "/<\/PSYCHOGENIC_ROOT_ELEMENT>/smi");
  683.         $replace = array($xmlhead,
  684.                 "");
  685.         $retString = preg_replace($search, $replace, $retString);
  686.  
  687.  
  688.         if (MINIXML_DEBUG > 0)
  689.         {
  690.             _MiniXMLLog("MiniXML::toString() Returning XML:\n$retString\n\n");
  691.         }
  692.         return $retString;
  693.     }
  694.  
  695.  
  696.     /* toArray
  697.     **
  698.     ** Transforms the XML structure currently represented by the MiniXML Document object
  699.     ** into an array.
  700.     **
  701.     ** More docs to come - for the moment, use var_dump($miniXMLDoc->toArray()) to see
  702.     ** what's going on :)
  703.     */
  704.  
  705.     function & toArray ()
  706.     {
  707.  
  708.         $retVal = $this->xxmlDoc->toStructure();
  709.  
  710.         if (is_array($retVal))
  711.         {
  712.             return $retVal;
  713.         }
  714.  
  715.         $retArray = array(
  716.                     '-content'    => $retVal,
  717.                 );
  718.  
  719.         return $retArray;
  720.     }
  721.  
  722.  
  723.     /* getValue()
  724.     ** Utility function, call the root MiniXMLElement's getValue()
  725.     */
  726.     function getValue ()
  727.     {
  728.         return $this->xxmlDoc->getValue();
  729.     }
  730.  
  731.  
  732.     /* dump
  733.     ** Debugging aid, dump returns a nicely formatted dump of the current structure of the
  734.     ** MiniXMLDoc object.
  735.     */
  736.     function dump ()
  737.     {
  738.         return serialize($this);
  739.     }
  740.  
  741.     // _extractAttributesFromString
  742.     // private method for extracting and setting the attributs from a
  743.     // ' a="b" c = "d"' string
  744.     function _extractAttributesFromString (&$element, &$attrString)
  745.     {
  746.  
  747.         if (! $attrString)
  748.         {
  749.             return NULL;
  750.         }
  751.  
  752.         $count = 0;
  753.         $attribs = array();
  754.         // Set the attribs
  755.         preg_match_all('/([^\s]+)\s*=\s*([\'"])([^\2]+?)\2/sm', $attrString, $attribs);
  756.  
  757.  
  758.         for ($i = 0; $i < count($attribs[0]); $i++)
  759.         {
  760.             $attrname = $attribs[1][$i];
  761.             $attrval = $attribs[3][$i];
  762.  
  763.             if ($attrname)
  764.             {
  765.                 $element->attribute($attrname, $attrval, '');
  766.                 $count++;
  767.             }
  768.         }
  769.  
  770.         return $count;
  771.     }
  772. }
  773.  
  774. /***************************************************************************************************
  775. ****************************************************************************************************
  776. *****
  777. *****                       MiniXML
  778. *****
  779. ****************************************************************************************************
  780. ***************************************************************************************************/
  781.  
  782. /* class MiniXML (MiniXMLDoc)
  783. **
  784. ** Avoid using me - I involve needless overhead.
  785. **
  786. ** Utility class - this is just an name aliase for the
  787. ** MiniXMLDoc class as I keep repeating the mistake of
  788. ** trying to create
  789. **
  790. ** $xml = new MiniXML();
  791. **
  792. */
  793. class MiniXML extends MiniXMLDoc {
  794.  
  795.     function MiniXML ()
  796.     {
  797.         $this->MiniXMLDoc();
  798.     }
  799. }
  800. ?>